home *** CD-ROM | disk | FTP | other *** search
- /*******************************************************************************
- +
- + LEDA 2.1.1 11-15-1991
- +
- +
- + graph.h
- +
- +
- + Copyright (c) 1991 by Max-Planck-Institut fuer Informatik
- + Im Stadtwald, 6600 Saarbruecken, FRG
- + All rights reserved.
- +
- *******************************************************************************/
-
-
- #ifndef GRAPHH
- #define GRAPHH
-
- /*------------------------------------------------------------------------------
-
- Graph
-
- Stefan Naeher
- FB10 Informatik
- Universitaet des Saarlandes
- 6600 Saarbruecken
-
- September 1988
-
- ------------------------------------------------------------------------------*/
-
-
- #include <LEDA\basic.h>
- #include <LEDA\list.h>
-
-
- //------------------------------------------------------------------------------
- /* declare node, edge, list(node) and list(edge) */
- //------------------------------------------------------------------------------
-
- class i_node;
- class i_edge;
-
- // node = pointer to internal node
- typedef i_node* node;
-
- // edge = pointer to internal edge
- typedef i_edge* edge;
-
-
- /* nodelist = doubly linked list of nodes */
- declare(list,node)
-
- /* list(edge) = doubly linked list of edges */
- declare(list,edge)
-
-
-
- //------------------------------------------------------------------------------
- // class i_node: internal representation of nodes
- //------------------------------------------------------------------------------
-
- class i_node {
-
- friend class graph;
- friend class ugraph;
- friend class planar_map;
-
- friend graph* graph_of(edge);
-
- graph* g; // pointer to graph
- int i_name; // internal name (index)
- list_item loc; // location in V
- int indegree;
- ent contents; // user defined pointer-type
- list(edge) adj_edges; /* list of adjacent edges */
-
- i_node(ent i)
- {
- contents=i;
- i_name = -1;
- g = 0;
- loc = 0;
- indegree = 0;
- }
-
- OPERATOR_NEW(10)
- OPERATOR_DEL(10)
-
- friend graph* graph_of(node v) { return v->g; }
- friend int indeg(node v) { return v->indegree; }
- friend int outdeg(node v) { return v->adj_edges.length(); }
- friend int degree(node v) { return v->adj_edges.length(); }
- friend int index(node v) { return v->i_name; }
-
- /* space : 5 words + 1 list = 20 + 20 bytes = 40 bytes */
- };
-
-
- //------------------------------------------------------------------------------
- // class i_edge: internal representation of edges
- //------------------------------------------------------------------------------
-
- class i_edge {
-
- friend class graph;
- friend class ugraph;
- friend class planar_map;
-
- friend graph* graph_of(edge);
-
- int i_name; // internal name (index)
- node s; // edge from "source"
- node t; // to "target"
- list_item loc; // location in |E|
- list_item adj_loc; // location in adjacencylist of source(e)
- list_item adj_loc2; // location in adjacencylist of target(e) (ugraph)
- ent contents; // user defined pointer type
-
- i_edge(node v, node w, ent i)
- { contents=i;
- i_name=-1;
- s=v;
- t=w;
- loc=0;
- adj_loc=0;
- adj_loc2=0;
- }
-
- OPERATOR_NEW(7)
- OPERATOR_DEL(7)
-
- friend node source(edge e) { return e->s; }
- friend node target(edge e) { return e->t; }
- friend int index(edge e) { return e->i_name; }
-
- //space : 7 words = 28 bytes
- };
-
-
- inline graph* graph_of(edge e) { return e->s->g; }
-
-
-
- typedef int (*COMPARE(graph,node)) (node&, node&);
- typedef int (*COMPARE(graph,edge)) (edge&, edge&);
-
-
- //------------------------------------------------------------------------------
- // Macro zur Definition von Feldern mit Indextyp node oder edge
- //------------------------------------------------------------------------------
-
- // declaration (itype = node/edge):
-
- #define graph_array(itype) name2(itype,graph_array)
-
- #define graph_arraydeclare(itype)\
- \
- class graph_array(itype) {\
- graph* g; /* array is declared for graph *g */ \
- int max_i; /* maximal node index in g at declaration time */ \
- ent* arr; \
- virtual void clear_entry(ent& x) const { x=0; }\
- virtual void copy_entry(ent& x) const { x=x; }\
- virtual void init_entry(ent& x) const { x=0; }\
- \
- public:\
- virtual int cmp_entry(itype x, itype y) const { return int(inf(x))-int(inf(y)); }\
- \
- ent& entry(itype);\
- ent inf(itype) const;\
- void init(const graph&, int, ent);\
- void init(const graph&, ent);\
- void init(const graph_array(itype)&);\
- void clear();\
- ent& elem(int i) { return arr[i]; }\
- int size() const { return max_i+1;}\
- graph_array(itype)() { g=0; max_i=(-1); arr=0;}\
- ~graph_array(itype)() { clear(); }\
- };\
-
-
- declare(graph_array,node)
- declare(graph_array,edge)
-
-
- //------------------------------------------------------------------------------
- // graph: base class for all graphs
- //------------------------------------------------------------------------------
-
- class graph {
-
- friend class ugraph;
- friend class planar_map;
-
- list(node) V; /* list of all nodes */
- list(edge) E; /* list of all edges */
-
- int max_node_index; // maximal node index
- int max_edge_index; // maximal edge index
-
- graph* parent; // for subgraphs
-
- bool undirected; // true iff graph undirected
-
- /* space: 2 lists + 4 words + "virtual" = 2*20 + 5*4 bytes = 60 bytes */
-
- virtual void init_node_entry(ent& x) const { x=0; }
- virtual void init_edge_entry(ent& x) const { x=0; }
-
- virtual void copy_node_entry(ent& x) const { x=x; }
- virtual void copy_edge_entry(ent& x) const { x=x; }
-
- virtual void clear_node_entry(ent& x) const { x=0; }
- virtual void clear_edge_entry(ent& x) const { x=0; }
-
- virtual void read_node_entry(istream& in, ent& x) const { Read(int(x),in); }
- virtual void read_edge_entry(istream& in, ent& x) const { Read(int(x),in); }
-
- virtual void write_node_entry(ostream& o, ent& x) const { Print(int(x),o); }
- virtual void write_edge_entry(ostream& o, ent& x) const { Print(int(x),o); }
-
- virtual void print_node_entry(ostream&, ent&) const {}
- virtual void print_edge_entry(ostream&, ent&) const {}
-
- virtual string node_type() const { return "void"; }
- virtual string edge_type() const { return "void"; }
-
- protected:
-
- void copy_all_entries();
-
- public:
-
- virtual int cmp_node_entry(node, node) const { return 0; }
- virtual int cmp_edge_entry(edge, edge) const { return 0; }
-
- int space() const;
- list(node) adj_nodes(node) const;
- void reset() const;
-
-
- int indeg(node v) const;
- int outdeg(node v) const;
- node source(edge e) const;
- node target(edge e) const;
-
- graph* super() const;
- int max_node_i() const;
- int max_edge_i() const;
-
- int number_of_nodes() const;
- int number_of_edges() const;
-
- list(node) all_nodes() const;
- list(edge) all_edges() const;
- list(edge) adj_edges(node v) const;
-
- ent& entry(node v);
- ent& entry(edge e);
- ent inf(node v) const;
- ent inf(edge e) const;
-
- void assign(node v,ent x);
- void assign(edge e,ent x);
-
-
- void init_node_iterator() const;
- void init_edge_iterator() const;
- int next_node(node& v) const;
- int prev_node(node& v) const;
- int next_edge(edge& e) const;
- int prev_edge(edge& e) const;
-
- edge first_adj_edge(node v) const;
- edge last_adj_edge(node v) const;
-
- void init_adj_iterator(node v) const;
- int next_adj_edge(edge& e,node v) const ;
- int current_adj_edge(edge& e,node v) const ;
- int next_adj_node(node& w,node v) const;
- int current_adj_node(node& w,node v) const;
-
- node first_node() const;
- edge first_edge() const;
- node last_node() const;
- edge last_edge() const;
- node choose_node() const;
- edge choose_edge() const;
- node succ_node(node v) const;
- node pred_node(node v) const;
- edge succ_edge(edge e) const;
- edge pred_edge(edge e) const;
- edge adj_succ(edge e) const;
- edge adj_pred(edge e) const;
- edge cyclic_adj_succ(edge e) const;
- edge cyclic_adj_pred(edge e) const;
-
-
- node new_node(ent);
- void del_node(node);
- void del_edge(edge);
- edge new_edge(node, node, ent);
- edge new_edge(edge, node, ent, int dir);
-
- node new_node() { ent x; init_node_entry(x);
- return new_node(x); }
-
- edge new_edge(node v, node w)
- { ent x; init_edge_entry(x);
- return new_edge(v,w,x);}
-
- edge new_edge(edge e, node w, int dir=0)
- { ent x; init_edge_entry(x);
- return new_edge(e,w,x,dir); }
-
-
- void del_all_nodes();
- void del_all_edges();
-
- list(edge) insert_reverse_edges();
-
- void sort_edges(COMPARE(graph,edge));
- void sort_nodes(COMPARE(graph,node));
-
- void sort_edges(const graph_array(edge)&);
- void sort_nodes(const graph_array(node)&);
-
- void sort_edges();
- void sort_nodes();
-
- edge rev_edge(edge);
- graph& rev();
-
- void make_directed();
- void make_undirected();
-
- void write(string s) const;
- int read (string s);
-
- void print_node(node,ostream& = cout) const;
-
- virtual void print_edge(edge,ostream& = cout) const; //different for ugraph's
-
- void print(string s, ostream& = cout) const;
-
- void print() const { print(""); }
- void print(ostream& o) const { print("",o); }
-
- void clear();
-
- graph();
- graph(const graph&);
- graph& operator=(const graph&);
-
- ~graph() { clear(); }
-
-
- //subgraph constructors
-
- graph(graph&, list(node)&, list(edge)&);
- graph(graph&, list(edge)&);
-
- };
-
- inline int graph::indeg(node v) const { return v->indegree; }
- inline int graph::outdeg(node v) const { return v->adj_edges.length(); }
- inline node graph::source(edge e) const { return e->s; }
- inline node graph::target(edge e) const { return e->t; }
-
- inline graph* graph::super() const { return parent; }
- inline int graph::max_node_i() const { return max_node_index; }
- inline int graph::max_edge_i() const { return max_edge_index; }
-
- inline int graph::number_of_nodes() const { return V.length(); }
- inline int graph::number_of_edges() const { return E.length(); }
-
- inline ent& graph::entry(node v) { return v->contents; }
- inline ent& graph::entry(edge e) { return e->contents; }
- inline void graph::assign(node v,ent x) { v->contents = x; }
- inline void graph::assign(edge e,ent x) { e->contents = x; }
-
- inline ent graph::inf(node v) const { return v->contents; }
- inline ent graph::inf(edge e) const { return e->contents; }
-
-
- inline void graph::init_node_iterator() const { V.init_iterator(); }
- inline void graph::init_edge_iterator() const { E.init_iterator(); }
- inline int graph::next_node(node& v) const { return V.next_element(v); }
- inline int graph::prev_node(node& v) const { return V.prev_element(v); }
- inline int graph::next_edge(edge& e) const { return E.next_element(e); }
- inline int graph::prev_edge(edge& e) const { return E.prev_element(e); }
- inline edge graph::first_adj_edge(node v) const { return v->adj_edges.head(); }
- inline edge graph::last_adj_edge(node v) const { return v->adj_edges.tail(); }
-
-
- inline void graph::init_adj_iterator(node v) const
- { v->adj_edges.init_iterator(); }
-
- inline int graph::next_adj_edge(edge& e,node v) const
- { return v->adj_edges.next_element(e); }
-
- inline int graph::current_adj_edge(edge& e,node v) const
- { return v->adj_edges.current_element(e);}
-
-
- inline int graph::next_adj_node(node& w,node v) const
- { edge e;
- if (next_adj_edge(e,v))
- { w = (v==e->s) ? e->t : e->s;
- return 1;
- }
- else { w = 0; return 0;}
- }
-
- inline int graph::current_adj_node(node& w,node v) const
- { edge e;
- if (current_adj_edge(e,v))
- { w = (v==e->s) ? e->t : e->s;
- return 1; }
- else { w = 0; return 0; }
- }
-
- inline node graph::first_node() const { return V.head(); }
- inline edge graph::first_edge() const { return E.head(); }
- inline node graph::last_node() const { return V.tail(); }
- inline edge graph::last_edge() const { return E.tail(); }
- inline node graph::choose_node() const { return V.head(); }
- inline edge graph::choose_edge() const { return E.head(); }
-
- inline node graph::succ_node(node v) const
- { list_item loc = V.succ(v->loc);
- return (loc) ? V.inf(loc) : 0;
- }
-
- inline node graph::pred_node(node v) const
- { list_item loc = V.pred(v->loc);
- return (loc) ? V.inf(loc) : 0;
- }
-
- inline edge graph::succ_edge(edge e) const
- { list_item loc = E.succ(e->loc);
- return (loc) ? E.inf(loc) : 0;
- }
-
- inline edge graph::pred_edge(edge e) const
- { list_item loc = E.pred(e->loc);
- return (loc) ? E.inf(loc) : 0;
- }
-
-
- inline edge graph::adj_succ(edge e) const
- { list_item loc = e->s->adj_edges.succ(e->adj_loc);
- return (loc) ? e->s->adj_edges[loc] : 0;
- }
-
- inline edge graph::adj_pred(edge e) const
- { list_item loc = e->s->adj_edges.pred(e->adj_loc);
- return (loc) ? e->s->adj_edges[loc] : 0;
- }
-
- inline edge graph::cyclic_adj_succ(edge e) const
- { list_item loc = e->s->adj_edges.cyclic_succ(e->adj_loc);
- return e->s->adj_edges[loc];
- }
-
- inline edge graph::cyclic_adj_pred(edge e) const
- { list_item loc = e->s->adj_edges.cyclic_pred(e->adj_loc);
- return e->s->adj_edges[loc];
- }
-
-
-
- //------------------------------------------------------------------------------
- // GRAPH: generic directed graphs
- //------------------------------------------------------------------------------
-
- #define GRAPH(vtype,etype) name3(vtype,etype,GRAPH)
-
- #define GRAPHdeclare2(vtype,etype)\
- class GRAPH(vtype,etype) : public graph {\
- \
- void init_node_entry(ent& x) const { x = Copy(vtype(0)); }\
- void init_edge_entry(ent& x) const { x = Copy(etype(0)); }\
- \
- void copy_node_entry(ent& x) const { Copy(*(vtype*)&x); }\
- void copy_edge_entry(ent& x) const { Copy(*(etype*)&x); }\
- \
- void clear_node_entry(ent& x) const { Clear(*(vtype*)&x); }\
- void clear_edge_entry(ent& x) const { Clear(*(etype*)&x); }\
- \
- void read_node_entry(istream& i, ent& x) const { Read(*(vtype*)&x,i); }\
- void read_edge_entry(istream& i, ent& x) const { Read(*(etype*)&x,i); }\
- \
- void write_node_entry(ostream& o, ent& x) const { Print(*(vtype*)&x,o); }\
- void write_edge_entry(ostream& o, ent& x) const { Print(*(etype*)&x,o); }\
- \
- void print_node_entry(ostream& o, ent& x) const\
- { o << "("; Print(*(vtype*)&x,o); o << ")"; }\
- void print_edge_entry(ostream& o, ent& x) const\
- { o << "("; Print(*(etype*)&x,o); o << ")"; }\
- \
- string node_type() const { return STRINGIZE(vtype); }\
- string edge_type() const { return STRINGIZE(etype); }\
- \
- public:\
- \
- int cmp_node_entry(node x, node y) const { return compare(inf(x),inf(y)); }\
- int cmp_edge_entry(edge x, edge y) const { return compare(inf(x),inf(y)); }\
- \
- vtype inf(node v) const { return vtype(graph::inf(v)); }\
- etype inf(edge e) const { return etype(graph::inf(e)); }\
- vtype& operator[] (node v) { return *(vtype*)&graph::entry(v); }\
- vtype operator[] (node v) const { return vtype(graph::inf(v)); }\
- etype& operator[] (edge e) { return *(etype*)&graph::entry(e); }\
- etype operator[] (edge e) const { return etype(graph::inf(e)); }\
- void assign(node v,vtype x) { graph::assign(v,Ent(x)); }\
- void assign(edge e,etype x) { graph::assign(e,Ent(x)); }\
- node new_node() { return graph::new_node(); }\
- node new_node(vtype a) { return graph::new_node(Copy(a)); }\
- edge new_edge(node v, node w)\
- { return graph::new_edge(v,w); }\
- edge new_edge(node v, node w, etype a)\
- { return graph::new_edge(v,w,Copy(a)); }\
- edge new_edge(edge e, node w)\
- { return graph::new_edge(e,w); }\
- edge new_edge(edge e, node w, etype a)\
- { return graph::new_edge(e,w,Copy(a),0); }\
- edge new_edge(edge e, node w, etype a, int dir)\
- { return graph::new_edge(e,w,Copy(a),dir); }\
- \
- GRAPH(vtype,etype)& operator=(const GRAPH(vtype,etype)& a)\
- {return (GRAPH(vtype,etype)&)(graph::operator=((graph&)a)); }\
- GRAPH(vtype,etype)() {}\
- GRAPH(vtype,etype)(const GRAPH(vtype,etype)& a) : graph((graph&)a) { copy_all_entries();} \
- /* sub graphs */\
- GRAPH(vtype,etype)(GRAPH(vtype,etype)& a, list(node)& b, list(edge)& c)\
- : graph((graph&)a,b,c) {}\
- GRAPH(vtype,etype)(GRAPH(vtype,etype)& a, list(edge)& c)\
- : graph((graph&)a,c) {}\
- ~GRAPH(vtype,etype)() { clear(); }\
- };
-
- //------------------------------------------------------------------------------
- // node arrays
- //------------------------------------------------------------------------------
-
- #define node_array(TYPE) name2(TYPE,node_array)
-
- #define node_arraydeclare(type)\
- \
- class node_array(type) : public graph_array(node) {\
- void copy_entry(ent& x) const { x = Copy(*(type*)&x); }\
- void clear_entry(ent& x) const { Clear(*(type*)&x); }\
- void init_entry(ent& x) const { x = Copy(type(0)); }\
- \
- public:\
- int cmp_entry(node x,node y) const { return compare(operator[](x),operator[](y)); }\
- \
- type& operator[](node x) { return *(type*)&graph_array(node)::entry(x);}\
- type operator[](node x) const { return type(graph_array(node)::inf(x));}\
- type& elem(int i) { return *(type*)&graph_array(node)::elem(i);}\
- void init(const graph& G, int n, type i)\
- { graph_array(node)::init(G,n,Ent(i)); }\
- void init(const graph& G, type i){ graph_array(node)::init(G,Ent(i)); }\
- void init(const graph& G) { type y=0; graph_array(node)::init(G,Ent(y)); }\
- void init(const node_array(type)& A)\
- { graph_array(node)::init((graph_array(node)&) A); }\
- \
- node_array(type)() {}\
- node_array(type)(const graph& G) { init(G); }\
- node_array(type)(const graph& G, int n, type i) { init(G,n,i); }\
- node_array(type)(const graph& G, type i) { init(G,i); }\
- node_array(type)(const node_array(type)& A) { init(A); }\
- node_array(type)& operator=(const node_array(type)& A) { init(A); return *this;}\
- \
- ~node_array(type)() { clear(); }\
- };
-
-
- //------------------------------------------------------------------------------
- // edge arrays
- //------------------------------------------------------------------------------
-
- #define edge_array(TYPE) name2(TYPE,edge_array)
-
- #define edge_arraydeclare(type)\
- \
- class edge_array(type) : public graph_array(edge) {\
- void copy_entry(ent& x) const { x = Copy(*(type*)&x); }\
- void clear_entry(ent& x) const { Clear(*(type*)&x); }\
- void init_entry(ent& x) const { x = Copy(type(0)); }\
- \
- public:\
- int cmp_entry(edge x,edge y) const { return compare(operator[](x),operator[](y)); }\
- \
- type& operator[](edge x) { return *(type*)&graph_array(edge)::entry(x);}\
- type operator[](edge x) const { return type(graph_array(edge)::inf(x));}\
- type& elem(int i) { return *(type*)&graph_array(edge)::elem(i);}\
- void init(const graph& G, int m, type i)\
- { graph_array(edge)::init(G,m,Ent(i)); }\
- void init(const graph& G, type i){ graph_array(edge)::init(G,Ent(i)); }\
- void init(const graph& G) { type y=0; graph_array(edge)::init(G,Ent(y)); }\
- void init(const edge_array(type)& A)\
- { graph_array(edge)::init((graph_array(edge)&) A); }\
- \
- edge_array(type)() {}\
- edge_array(type)(const graph& G) { init(G); }\
- edge_array(type)(const graph& G, int m, type i) { init(G,m,i); }\
- edge_array(type)(const graph& G, type i) { init(G,i); }\
- edge_array(type)(const edge_array(type)& A) { init(A); }\
- edge_array(type)& operator=(const edge_array(type)& A) { init(A); return *this;}\
- \
- ~edge_array(type)() { clear(); }\
- };
-
- //------------------------------------------------------------------------------
- // node matrices
- //------------------------------------------------------------------------------
-
- typedef graph_array(node)* node_array_ptr;
-
- declare(node_array,node_array_ptr);
-
- class Node_Matrix {
- graph* g;
- node_array(node_array_ptr) M;
- virtual void init_entry(ent& x) const { x=0; }
- virtual void copy_entry(ent& x) const { x=x; }
- virtual void clear_entry(ent& x) const { x=0; }
- virtual void print_entry(ent& x) const { Print(x); }
- public:
- graph_array(node)& operator[](node v);
- ent& entry(node, node);
- ent inf(node, node) const;
- void clear();
- void init(const graph&, int, ent);
- void init(const graph&, ent);
- void init(Node_Matrix&);
- Node_Matrix() {}
- ~Node_Matrix() { clear(); }
- };
-
-
- #define node_matrix(type) name2(type,node_matrix)
-
- #define node_matrixdeclare(type)\
- \
- class node_matrix(type): public Node_Matrix {\
- void copy_entry(ent& x) const { x = Copy(*(type*)&x); }\
- void clear_entry(ent& x) const { Clear(*(type*)&x); }\
- void init_entry(ent& x) const { x = Copy(type(0)); }\
- void print_entry(ent& x) const { Print(*(type*)&x); }\
- public:\
- node_array(type)& operator[](node v)\
- { return *(node_array(type)*)&(Node_Matrix::operator[](v)); }\
- \
- type& operator()(node v, node w) { return *(type*)&(Node_Matrix::entry(v,w));}\
- type operator()(node v, node w) const { return type(Node_Matrix::inf(v,w)); }\
- \
- void init(const graph& G, int n, type i) { Node_Matrix::init(G,n,Ent(i)); }\
- void init(const graph& G, type i) { Node_Matrix::init(G,Ent(i)); }\
- void init(const graph& G) { type y = 0; Node_Matrix::init(G,Ent(y)); }\
- void init(const node_matrix(type)& M) { Node_Matrix::init((Node_Matrix&) M); }\
- \
- node_matrix(type)() {}\
- node_matrix(type)(const graph& G) { init(G); }\
- node_matrix(type)(const graph& G, int n, type x) { init(G,n,x); }\
- node_matrix(type)(const graph& G, type x) { init(G,x); }\
- node_matrix(type)(const node_matrix(type)& M) { init(M); }\
- \
- node_matrix(type)& operator=(const node_matrix(type)& M){init(M);return *this;}\
- \
- ~node_matrix(type)() { clear(); }\
- };\
-
-
- //------------------------------------------------------------------------------
- // Iteration (macros)
- //------------------------------------------------------------------------------
-
- /*
- #define forall_nodes(a,b) for ((b).init_node_iterator(); (b).next_node(a); )
- #define forall_edges(a,b) for ((b).init_edge_iterator(); (b).next_edge(a); )
- */
-
- #define forall_nodes(a,g) for (a=(g).first_node(); a; a=(g).succ_node(a) )
-
- #define forall_edges(a,g) for (a=(g).first_edge(); a; a=(g).succ_edge(a) )
-
- #define forall_adj_edges(a,b)\
- for (graph_of(b)->init_adj_iterator(b); graph_of(b)->next_adj_edge(a,b); )
-
- /*
- #define forall_adj_edges(a,b)\
- for (a=graph_of(b)->first_adj_edge(b); a; a=graph_of(b)->adj_succ(a) ) */
-
-
- #define forall_adj_nodes(a,b)\
- for (graph_of(b)->init_adj_iterator(b); graph_of(b)->next_adj_node(a,b); )
-
- #define forall_node_pairs(a,b,g)\
- forall_nodes(a,g) for (b=(g).first_node(); b; b=(g).succ_node(b) )
-
-
- // reverse
-
- #define Forall_nodes(a,g) for (a=(g).last_node(); a; a=(g).pred_node(a) )
-
- #define Forall_edges(a,g) for (a=(g).last_edge(); a; a=(g).pred_edge(a) )
-
-
-
- //-----------------------------------------------------------------------------
- // miscellaneous (should be members or constructors)
- //-----------------------------------------------------------------------------
-
- extern void eliminate_parallel_edges(graph& G);
-
- extern void complete_graph(graph&,int);
- extern void random_graph(graph&,int,int);
- extern void random_planar_graph(graph&,int);
-
- extern void test_graph(graph&);
- extern void test_bigraph(graph&, list(node)&, list(node)&);
-
- #endif
-
-